Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

980
Visualizações
[Node.js, sharp]: Make text take up 100% of SVG width

I am using the sharp image library to add text labels to an image. The only way to add text to an image using sharp is by creating an svg and using the composite function to apply it onto the source image.

let width = 100;
let height = 25;
let label = "Loooooooooong Text"; // "Medium Text" "Short"

const label = Buffer.from(`
    <svg width="${width}" height="${height}">
        <rect x="0" y="0" width="100%" height="100%" fill="#fff" />
        <text x="50%" y="50%" text-anchor="middle" dy="0.25em" fill="#000">${label}</text>
    </svg>
`);

let image = await sharp({
    create: {
        width: width,
        height: height,
        channels: 4,
        background: { r: 255, g: 255, b: 255, alpha: 1 },
    }
}).composite([{
    input: label,
    top: 0,
    left: 0,
}]).png().toBuffer();

However, I am having trouble getting the text use the space available in the container properly. Text should be centered vertically and horizontally within the svg. Text should be as tall as it is possible without overflowing the container horizontally.

This is what my code produces with different values for label:

enter image description here

This is ideally what I would like it to produce:

enter image description here

Additionally, because of an issue in sharp I cannot use dominant-baseline="middle" to center my text vertically and instead must use dy="0.25em". I'm not sure if this would change the answer but I thought it noteworthy to include.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

You can use viewBox

const sharp = require('sharp');

const width = 100;
const height = 25;
const label = "Loooooooooong Text"; // "Medium Text" "Short"

const svg = `
<svg width="${width}" height="${height}" viewBox="0 0 ${height} ${height + 2}">
  <!--this rect should have rounded corners-->
  <rect x="0" y="0" width="100%" height="100%" fill="#fff"/>
  <text x="50%" y="50%" text-anchor="middle" dy="0.25em" fill="#000">${label}</text>
</svg>
`;

const svg_buffer = Buffer.from(svg);
const image = sharp({
    create: {
        width: width,
        height: height,
        channels: 4,
        background: { r: 255, g: 255, b: 255, alpha: 1 },
    }
})
  .composite([{
    input: svg_buffer,
    top: 0,
    left: 0,
}])
  .png()
  .toFile('sample.png');
over 4 years ago · Santiago Trujillo Relatório

0

I think You have to change height accordingly.

let width = 100;
let height = 25;
let label = "Loooooooooong  Text ";
let lengthoftext =20;

So lets assume this is perfect fitted text scenario. Now let's think text is just 10 char. so you keep width=100 but change height = 50;
and so on you take ratio heightnew = (20/lengthoftext) *25. I think all text should be same size you can just make sure what is max length and then you wrap it in next line.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda